import os
import uuid
import pytz

from datetime import datetime
from docxtpl import DocxTemplate, InlineImage
from docx.shared import Cm, Mm
from app.config.db import DBUtils

from app.service.OpponentCharactersService_Pandas import OpponentCharactersServicePandas
from app.service.SettlementPreferenceService import SettlementPreferenceService
from app.service.UserPortraitService import UserPortraitService
from app.service.capitalRiskService import CapitalRiskService
from app.service.portraitJyfxSffxTabService import PortraitJyfxSffxTabService
from app.service.sjkzrService import SjkzrService
from app.service.transactionFeaturesService import TransactionFeatures
from app.utils.ChartGenerationUtils import ChartGenerationUtils

user_portrait = UserPortraitService()
portraitJyfxSffxTab = PortraitJyfxSffxTabService()
transactionFeatures = TransactionFeatures()
opponentCharactersServicePandas = OpponentCharactersServicePandas()
settlementPreferenceService = SettlementPreferenceService()
capitalRiskService = CapitalRiskService()
sjkzrService = SjkzrService()

class ReportGenerationService:

    def __init__(self):
        self.db_utils = DBUtils()

    def generationReport(self, session, report_tmp_path, report_chart_path, report_save_path,  company_name, year, start_date, end_date):
        try:
            # 工商信息
            gsxx = user_portrait.select_company_info(session, company_name)
            # 封面信息
            fm = {
                "gsmc": company_name,
                "type": "成员单位" if int(gsxx[0].get("IS_CYDW")) == 1 else "交易对手",
                "year": datetime.now().year,
                "month": datetime.now().month,
                "day": datetime.now().day,
            }
            # 企业评分
            qypf_data = user_portrait.select_score_info(session, company_name)
            qypf = {
                "composite_score":qypf_data[0].get("composite_score") if len(qypf_data) > 0 else '暂无评',
                "bank_score": qypf_data[0].get("bank_score") if len(qypf_data) > 0 else '暂无评'
            }
            # 股东信息
            gdxx_list = user_portrait.select_user_position(session, company_name)
            # 交易指标
            jyzb_data = transactionFeatures.select_trading_indicators_data(session, company_name,
                                                                      int(gsxx[0].get("IS_CYDW")), year)
            jyzb = jyzb_data.get("jyzb") if len(jyzb_data) > 0 else None
            # 交易统计-上游
            jytj_sy_labels = []
            jytj_sy_values = []
            # 交易统计-下游
            jytj_xy_labels = []
            jytj_xy_values = []
            if len(jyzb_data) > 0:
                for item in jyzb_data.get("jytj").get("sy_jy_list"):
                    for key, value in item.items():
                        jytj_sy_labels.append(key)
                        jytj_sy_values.append(value)
                for item in jyzb_data.get("jytj").get("xy_jy_list"):
                    for key, value in item.items():
                        jytj_xy_labels.append(key)
                        jytj_xy_values.append(value)
            jytj_sy = {
                "title": "上游交易金额",
                "labels": jytj_sy_labels,
                "values": jytj_sy_values,
                "xlabel": "单位：月",
                "ylabel": "交易金额（万元）"
            }
            jytj_sy_chart_path = os.path.join(report_chart_path, f"jytj_sy_{uuid.uuid4().hex}.png")
            ChartGenerationUtils.create_barchart_image(jytj_sy_chart_path, jytj_sy)
            jytj_xy = {
                "title": "下游交易金额",
                "labels": jytj_xy_labels,
                "values": jytj_xy_values,
                "xlabel": "单位：月",
                "ylabel": "交易金额（万元）"
            }
            jytj_xy_chart_path = os.path.join(report_chart_path, f"jytj_xy_{uuid.uuid4().hex}.png")
            ChartGenerationUtils.create_barchart_image(jytj_xy_chart_path, jytj_xy)
            # 对手特征-行业分布
            dstz_data = opponentCharactersServicePandas.select_hyfb_data(session, company_name, int(gsxx[0].get("IS_CYDW")),
                                                                    start_date, end_date)
            # 上游
            dstz_sy_ratio_labels = []
            dstz_sy_ratio_values = []
            # 下游
            dstz_xy_ratio_labels = []
            dstz_xy_ratio_values = []
            # 上游
            dstz_sy_count_labels = []
            dstz_sy_count_values = []
            # 下游
            dstz_xy_count_labels = []
            dstz_xy_count_values = []
            if len(dstz_data) > 0:
                # 行业类型占比
                sy_ratio_list = dstz_data.get("dshy_info").get("sxy_pie_chart").get("sy_gbhyml_num_list")
                xy_ratio_list = dstz_data.get("dshy_info").get("sxy_pie_chart").get("xy_gbhyml_num_list")
                for item in sy_ratio_list:
                    dstz_sy_ratio_labels.append(item["name"])
                    dstz_sy_ratio_values.append(item["value"])
                for item in xy_ratio_list:
                    dstz_xy_ratio_labels.append(item["name"])
                    dstz_xy_ratio_values.append(item["value"])
                # 上下游数量统计
                sy_count_list = dstz_data.get("dshy_info").get("sxy_statistics").get("sy_normalized_list")
                xy_count_list = dstz_data.get("dshy_info").get("sxy_statistics").get("xy_normalized_list")
                for item in sy_count_list:
                    dstz_sy_count_labels.append(item["name"])
                    dstz_sy_count_values.append(item["value"])
                for item in xy_count_list:
                    dstz_xy_count_labels.append(item["name"])
                    dstz_xy_count_values.append(item["value"])
            dstz_sy_ratio = {
                "title": "上游行业类型占比",
                "labels": dstz_sy_ratio_labels,
                "values": dstz_sy_ratio_values,
            }
            dstz_sy_pie_path = os.path.join(report_chart_path, f"dstz_sy_ratio_{uuid.uuid4().hex}.png")
            ChartGenerationUtils.create_piechart_image(dstz_sy_pie_path, dstz_sy_ratio)
            dstz_xy_ratio = {
                "title": "下游行业类型占比",
                "labels": dstz_xy_ratio_labels,
                "values": dstz_xy_ratio_values,
            }
            dstz_xy_pie_path = os.path.join(report_chart_path, f"dstz_xy_ratio_{uuid.uuid4().hex}.png")
            ChartGenerationUtils.create_piechart_image(dstz_xy_pie_path, dstz_xy_ratio)
            dstz_sy_count = {
                "title": "上游数量统计",
                "labels": dstz_sy_count_labels,
                "values": dstz_sy_count_values,
                "xlabel": "单位：种",
                "ylabel": "单位：%"
            }
            dstz_sy_bar_path = os.path.join(report_chart_path, f"dstz_sy_count_{uuid.uuid4().hex}.png")
            ChartGenerationUtils.create_barchart_image(dstz_sy_bar_path, dstz_sy_count)
            dstz_xy_count = {
                "title": "下游数量统计",
                "labels": dstz_xy_count_labels,
                "values": dstz_xy_count_values,
                "xlabel": "单位：种",
                "ylabel": "单位：%"
            }
            dstz_xy_bar_path = os.path.join(report_chart_path, f"dstz_xy_count_{uuid.uuid4().hex}.png")
            ChartGenerationUtils.create_barchart_image(dstz_xy_bar_path, dstz_xy_count)
            # 结算偏好-交易指标
            jsph_jyzb = settlementPreferenceService.select_trading_indicators_data(session, company_name,
                                                                                   int(gsxx[0].get("IS_CYDW")),
                                                                                   start_date, end_date)
            # 结算偏好-结算统计
            jsph_data = settlementPreferenceService.select_settlement_statistics_data(session, company_name,
                                                                                 int(gsxx[0].get("IS_CYDW")),
                                                                                 start_date, end_date)
            # 票据
            jsph_pj_labels = []
            jsph_pj_values = []
            # 现金
            jsph_xj_labels = []
            jsph_xj_values = []
            if len(jsph_data) > 0:
                for item in jsph_data.get("pj_y_je_list"):
                    jsph_pj_labels.append(item.get("name"))
                    jsph_pj_values.append(item.get("value"))
                for item in jsph_data.get("xj_y_je_list"):
                    jsph_xj_labels.append(item.get("name"))
                    jsph_xj_values.append(item.get("value"))
            jsph_pj = {
                "title": "票据结算",
                "labels": jsph_pj_labels,
                "values": jsph_pj_values,
                "xlabel": "单位：月",
                "ylabel": "交易金额（万元）"
            }
            jsph_pj_chart_path = os.path.join(report_chart_path, f"jsph_pj_{uuid.uuid4().hex}.png")
            ChartGenerationUtils.create_barchart_image(jsph_pj_chart_path, jsph_pj)
            jsph_xj = {
                "title": "现金结算",
                "labels": jsph_xj_labels,
                "values": jsph_xj_values,
                "xlabel": "单位：月",
                "ylabel": "交易金额（万元）"
            }
            jsph_xj_chart_path = os.path.join(report_chart_path, f"jsph_xj_{uuid.uuid4().hex}.png")
            ChartGenerationUtils.create_barchart_image(jsph_xj_chart_path, jsph_xj)
            # 资金风险-司库风险监测
            zjfx_data = capitalRiskService.select_capital_risk(session, company_name, year)
            zjfx_skfxjc = zjfx_data.get("risk_total") if zjfx_data is not None else None
            zjfx_skfxjc_list = zjfx_data.get("details_total") if zjfx_data is not None else None
            # 资金风险-司库风险线索
            zjfx_skfxxs_list = user_portrait.select_risk_history(session, company_name)
            # 疑似实际控制人
            yssjkzr_list = sjkzrService.select_sjkzr_by_company(session, company_name)
            # 经营风险
            jyfx_gscg_list = portraitJyfxSffxTab.select_jyfx_gscg(session, company_name)
            jyfx_gqcz_list = portraitJyfxSffxTab.select_jyfx_gqcz(session, company_name)
            jyfx_sxxx_list = portraitJyfxSffxTab.select_jyfx_sxxx(session, company_name)
            jyfx_gqzy_list = portraitJyfxSffxTab.select_jyfx_gqzy(session, company_name)
            jyfx_dcdy_list = portraitJyfxSffxTab.select_jyfx_dcdy(session, company_name)
            jyfx_jyyc_list = portraitJyfxSffxTab.select_jyfx_jyyc(session, company_name)
            # 司法风险
            sffx_sfxz_list = portraitJyfxSffxTab.select_sffx_sfxz(session, company_name)
            sffx_ktgg_list = portraitJyfxSffxTab.select_sffx_ktgg(session, company_name)
            sffx_qsgg_list = portraitJyfxSffxTab.select_sffx_qsgg(session, company_name)
            sffx_flss_list = portraitJyfxSffxTab.select_sffx_flss(session, company_name)
            sffx_fygg_list = portraitJyfxSffxTab.select_sffx_fygg(session, company_name)
            sffx_hbcf_list = portraitJyfxSffxTab.select_sffx_hbcf(session, company_name)
            sffx_laxx_list = portraitJyfxSffxTab.select_sffx_laxx(session, company_name)
            sffx_zbaj_list = portraitJyfxSffxTab.select_sffx_zbaj(session, company_name)
            sffx_xzcf_list = portraitJyfxSffxTab.select_sffx_xzcf(session, company_name)
            sffx_bzxrxx_list = portraitJyfxSffxTab.select_sffx_bzxrxx(session, company_name)
            sffx_sdgg_list = portraitJyfxSffxTab.select_sffx_sdgg(session, company_name)
            sffx_xzxfl_list = portraitJyfxSffxTab.select_sffx_xzxfl(session, company_name)
            doc_tmp = DocxTemplate(report_tmp_path)
            # 报告内容
            content = {
                'fm': fm, # 封面
                'gsxx': gsxx[0],  # 基本信息
                'qypf': qypf,  # 企业评分
                'gdxx_list': gdxx_list,  # 股东信息
                'jyzb': jyzb,  # 交易指标
                'jytj_sy': InlineImage(doc_tmp, jytj_sy_chart_path, width=Mm(155)),  # 交易统计-上游
                'jytj_xy': InlineImage(doc_tmp, jytj_xy_chart_path, width=Mm(155)),  # 交易统计-下游
                'dstz_hylxzb_sy': InlineImage(doc_tmp, dstz_sy_pie_path, width=Mm(155)),  # 对手特征-行业分布-行业类型占比-上游
                'dstz_hylxzb_xy': InlineImage(doc_tmp, dstz_xy_pie_path, width=Mm(155)),  # 对手特征-行业分布-行业类型占比-下游
                'dstz_sltj_sy': InlineImage(doc_tmp, dstz_sy_bar_path, width=Mm(155)),  # 对手特征-行业分布-数量统计-上游
                'dstz_sltj_xy': InlineImage(doc_tmp, dstz_xy_bar_path, width=Mm(155)),  # 对手特征-行业分布-数量统计-下游
                'jsph_jyzb': jsph_jyzb,  # 结算偏好-交易指标
                'jsph_jytj_pj': InlineImage(doc_tmp, jsph_pj_chart_path, width=Mm(155)),  # 结算偏好-交易统计-票据
                'jsph_jytj_xj': InlineImage(doc_tmp, jsph_xj_chart_path, width=Mm(155)),  # 结算偏好-交易统计-现金
                'zjfx_skfxjc': zjfx_skfxjc,  # 资金风险-司库风险监测
                'zjfx_skfxjc_list': zjfx_skfxjc_list,  # 资金风险-司库风险监测
                'zjfx_skfxxs_list': zjfx_skfxxs_list,  # 资金风险-司库风险线索
                'yssjkzr_list': yssjkzr_list,  # 疑似实际控制人
                'jyfx_gscg_list': jyfx_gscg_list,  # 经营风险-公示催告
                'jyfx_gqcz_list': jyfx_gqcz_list,  # 经营风险-股权出质
                'jyfx_sxxx_list': jyfx_sxxx_list,  # 经营风险-失信信息
                'jyfx_gqzy_list': jyfx_gqzy_list,  # 经营风险-股权质押
                'jyfx_dcdy_list': jyfx_dcdy_list,  # 经营风险-动产抵押
                'jyfx_jyyc_list': jyfx_jyyc_list,  # 经营风险-经营异常
                'sffx_sfxz_list': sffx_sfxz_list,  # 司法风险-司法协助
                'sffx_ktgg_list': sffx_ktgg_list,  # 司法风险-开庭公告
                'sffx_qsgg_list': sffx_qsgg_list,  # 司法风险-欠税公告
                'sffx_flss_list': sffx_flss_list,  # 司法风险-法律诉讼
                'sffx_fygg_list': sffx_fygg_list,  # 司法风险-法院公告
                'sffx_hbcf_list': sffx_hbcf_list,  # 司法风险-环保处罚
                'sffx_laxx_list': sffx_laxx_list,  # 司法风险-立案信息
                'sffx_zbaj_list': sffx_zbaj_list,  # 司法风险-终本案件
                'sffx_xzcf_list': sffx_xzcf_list,  # 司法风险-行政处罚
                'sffx_bzxrxx_list': sffx_bzxrxx_list,  # 司法风险-被执行人信息
                'sffx_sdgg_list': sffx_sdgg_list,  # 司法风险-送达公告
                'sffx_xzxfl_list': sffx_xzxfl_list,  # 司法风险-限制消费令
            }
            doc_tmp.render(content)
            doc_tmp.save(report_save_path)
            return {
                "result": 1,
                "content": content
            }
        except Exception as e:
            print(e)
            return {
                "result": 0,
                "content": None
            }